﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <map>
#include <string>
using namespace std;


//饿汉模式：提前(main函数启动时)创建好实例对象
//优点：实现简单
//缺点：1.可能会导致进程启动慢
//2.如果有两个单例启动先后顺序，那么饿汉无法控制
//假设有两个单例A B，要求A单例先启动，B再启动(因为B需要调用A)
//静态对象可以理解为全局对象，先初始化谁无法控制
//class A {
//public:
//	////如果 GetInstance() 不是静态的，就必须先有一个 A 的对象才能调用它，但构造函数是私有的，无法创建对象 → 死锁。
//	////因此，必须通过 static 方法直接访问 _inst，而不依赖任何实例。
//	//A* GetInstance() { return &_inst; }
//
//	static A* GetInstance() { return &_inst; }
//
//	void Add(const string& key, const string& value) {
//		_dict[key] = value;
//	}
//
//	void Print() {
//		for (auto& kv : _dict)
//			cout << kv.first << ":" << kv.second << endl;
//		cout << endl;
//	}
//private:
//	A() {};
//	A(const A& aa) = delete;
//	A& operator=(const A& aa) = delete;//禁用拷贝构造最好也禁用赋值
//	map<string, string> _dict;
//	int _n = 0;
//
//	//静态成员变量属于类本身，而不是类的某个特定对象（因此，A::_inst是一个全局唯一的A类对象）
//	//静态成员的定义是在类的作用域内完成的，所以可以访问私有构造函数
//	static A _inst;
//};
//A A::_inst;
//
//int main() {
//	A::GetInstance()->Add("sort", "排序");
//	A::GetInstance()->Add("left", "左边");
//	A::GetInstance()->Add("right", "右边");
//	A::GetInstance()->Print();
//
//	////该类仍有缺陷，还要禁用拷贝构造
//	//A copy(*A::GetInstance());
//	//copy.Print();
//
//	//A::GetInstance()->Add("left", "剩余");
//	//A::GetInstance()->Print();//这个改了
//	//copy.Print();//这个没改
//
//	//*A::GetInstance() = *A::GetInstance();//禁用赋值，避免自己给自己赋值
//
//	return 0;
//}



//懒汉模式：第一次用的时候再创建
//懒汉模式的线程安全问题：在多线程环境下，如果多个线程同时首次调用 GetInstance()，
//可能会导致单例对象被构造多次，从而破坏单例的唯一性。
//new的懒汉对象一般不需要释放，进程正常结束会释放资源
class B {
public:
	//第一次调用该函数，_inst为空，创建B对象。
	//第二次调用该函数，_inst不为空，直接返回_inst
	static B* GetInstance() { 
		if (_inst == nullptr)
			_inst = new B;
		return _inst;
	}

	void Add(const string& key, const string& value) {
		_dict[key] = value;
	}

	void Print() {
		for (auto& kv : _dict)
			cout << kv.first << ":" << kv.second << endl;
		cout << endl;
	}

	//DelInstance()确实提供了双重功能：
	//a) 作为gc类的自动释放接口
	//b) 作为用户手动释放的接口
	static void DelInstance() {
		if (_inst) {
			delete _inst;//这里会调用析构
			_inst = nullptr;
		}
	}
private:
	B() {};
	~B() {
		//持久化：要求把数据写到文件
		cout << "数据写到文件" << endl;
	}
	B(const B& aa) = delete;
	B& operator=(const B& aa) = delete;//禁用拷贝构造最好也禁用赋值
	map<string, string> _dict;
	int _n = 0;

	//静态成员变量属于类本身，而不是类的某个特定对象（因此，A::_inst是一个全局唯一的A类对象）
	//静态成员的定义是在类的作用域内完成的，所以可以访问私有构造函数
	static B* _inst;

	//内部类是外部类的友元
	//gc类在这里相当于在懒汉模式中嵌入了一个"饿汉式"的辅助对象。
	//gc类的实例_gc是静态成员，会在程序启动时初始化（饿汉式）。
	//gc的析构函数会调用DelInstance()来释放单例对象。
	class gc {
	public:
		~gc() { DelInstance(); }
	};
	static gc _gc;
};
B* B::_inst = nullptr;
B::gc B::_gc;
//B::gc：表示这是 B 类内部的嵌套类 gc 类型。
//B::_gc：表示这是 B 类的静态成员变量 _gc。

int main() {
	B::GetInstance()->Add("sort", "排序");
	B::GetInstance()->Add("left", "左边");
	B::GetInstance()->Add("right", "右边");
	B::GetInstance()->Print();

	return 0;
}